<?php

namespace app\common\library\xmwechat\payment;

use app\common\library\xmwechat\SingletonTrait;
use app\common\library\xmwechat\WechatService;
use EasyWeChat\Pay\Application;
use Symfony\Component\HttpClient\Exception\ClientException;
use Symfony\Component\HttpClient\Exception\ServerException;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;

/**
 * 微信支付
 */
class PayService extends WechatService
{
    protected ?Application $app = null;

    use SingletonTrait;

    public function __construct()
    {
        parent::__construct();
        if (empty($this->wechatPayConfig['mch_id']) || empty($this->wechatPayConfig['secret_key'])) {
            $this->result('请配置商户号或商户密钥Key');
        }
        $payConfig = [
            'mch_id'      => $this->wechatPayConfig['mch_id'],
            'secret_key'  => $this->wechatPayConfig['secret_key'],
            'certificate' => root_path() . $this->wechatPayConfig['certificate'],
            'private_key' => root_path() . $this->wechatPayConfig['private_key'],
            'notify_url'  => $this->wechatPayConfig['notify_url'],
            'http'        => [
                'throw'   => true, // 状态码非 200、300 时是否抛出异常，默认为开启
                'timeout' => 5.0,
            ],
        ];
        $this->app = new Application($payConfig);
    }


    /**
     * 微信公众号、小程序发起支付
     * @return bool|array
     * @throws ClientExceptionInterface
     * @throws DecodingExceptionInterface
     * @throws RedirectionExceptionInterface
     * @throws ServerExceptionInterface
     * @throws TransportExceptionInterface
     * @throws \Exception
     * @author jsjxsz <QQ:1365962177>
     */
    public function pay($params): bool|array
    {
        try {
            // order_no:订单号，body:描述，pay_price:支付金额， openid：当前用户openid
            $order_no = $params['order_no'];
            $response = $this->app->getClient()->postJson("/v3/pay/transactions/jsapi", [
                "mchid"        => $this->wechatPayConfig['mch_id'],
                "out_trade_no" => $params['transaction_no'],// 交易号
                "appid"        => $this->miniProgramConfig['app_id'],
                "description"  => $params['body'],
                "notify_url"   => $this->wechatPayConfig['notify_url'],
                "amount"       => [
                    "total"    => intval($params['pay_price'] * 100),
                    "currency" => "CNY"
                ],
                "payer"        => [
                    "openid" => $params['openid']
                ]
            ]);
            $result   = $response->toArray();
            if (!empty($result['prepay_id'])) {
                $prepayId  = $result['prepay_id'];
                $utils     = $this->app->getUtils();
                //微信小程序appid; 公众号支付需用公众号appid
                $appId     = $params['pay_type'] == 'miniProgram' ? $this->miniProgramConfig['app_id'] : $this->offiAccountConfig['app_id'];
                // 默认RSA，v2要传MD5
                $signType  = 'RSA';
                $payResult = $utils->buildBridgeConfig($prepayId, $appId, $signType);
                if (isset($payResult['paySign']) && !empty($payResult['paySign'])) {

                    // 若有逻辑 这里写你自己的逻辑
                    // 此接口不代表支付成功，只是给客户端提供参数，调起支付
                    // 支付成功逻辑处理请在支付回调接口处理

                    // 此参数返回客户端，客户端拿到参数调起支付
                    return $payResult;
                }
            }
            return false;
        } catch (ServerException|ClientException $err) {
            $this->result($err->getResponse()->getContent(false));
        } catch (\Exception $exception) {
            $this->result($exception->getMessage());
        }
    }

}